#!/usr/bin/perl
use strict;
use DBI;
use IO::Socket;
use modules::encode;
use modules::parse;
use modules::modes;
use modules::nicks;
use modules::server;
use modules::motd;

use cs::csopme;
use cs::csop;
use cs::cshelp;
use cs::csversion;
use cs::csuptime;
use cs::csinfo;
use cs::csregister;
use cs::csaccess;
use cs::csdrop;
use cs::csadd;
use cs::csremove;
use cs::csedit;
use cs::cslist;
use cs::csaop;
use cs::csvoiceme;
use cs::csinvite;
use cs::csvoice;
use cs::cscycle;
use cs::csseturl;
use cs::csdeop;

use ns::nshelp;
use ns::nsregister;
use ns::nsmyinfo;
use ns::nsnewpass;
use ns::nsidentify;
use ns::nsinfo;
use ns::nswhois;
use ns::nsunregister;
use ns::nsrecover;

use os::osregister;
use os::osopers;
#use os::osregchan;

use ms::mshelp;

if ($ARGV[0] eq '-h') {
    print "Usage : $0 [-d]\n";
    exit;
}

###################
#VARYING VARIABLES#
###################
my $debug = 0; $debug = 1 if $ARGV[0] eq '-d';
my $cdebug = 1;
my $servername = 'services.maxismedia.net';
my $num = 'A[';
my $pass = '200391';
my $descrip = '[202.157.186.27] MaxisMedia IRC Services';
my $VER = 'CSWorld 3.9.(development)';

my $host = '202.157.186.27';
my $port = '4400';

my $bothost = 'maxismedia.net';
my $csnum = 'A[AAA';
my $csnick = 'M';
my $csname = 'Channel Services';
my $csident = 'chanserv';
my $nsnick = 'NS';
my $nsnum = 'A[AAB';
my $nsname = 'NickName Services';
my $nsident = 'nickserv';
my $osnum = 'A[AAC';
my $osnick = 'M2';
my $osname = 'IRC Operator Services';
my $osident = 'operserv';
my $msnum = 'A[AAD';
my $msnick = 'MS';
my $msident = 'memoserv';
my $msname = 'Memo Services';
my $NETWORK = 'MaxisMedia';
###################

my $dbh;
my $sth;
my $remote;
my %cbans;
my $EA = 0;

$dbh = DBI->connect("DBI:mysql:csworld:127.0.0.1", "tonberry", "kewlnet") or die "Cannot connect to DB\n";


$sth = $dbh->prepare("drop table if exists onchan;");
$sth->execute;
$sth = $dbh->prepare("drop table if exists server;");
$sth->execute;
$sth = $dbh->prepare("drop table if exists uptime;");
$sth->execute;
$sth=$dbh->prepare("DROP TABLE IF EXISTS ninfo;");
$sth->execute;
$sth=$dbh->prepare("Drop table if exists bans;");
$sth->execute;

$sth=$dbh->prepare("CREATE TABLE bans (channel varchar(20), mask varchar(255));");
$sth->execute;
$sth = $dbh->prepare("CREATE TABLE ninfo (num char(5), nick varchar(9), host varchar(100), auth varchar (9), oper int(1), server varchar(40), code int(5));");
$sth->execute;
$sth = $dbh->prepare("CREATE TABLE onchan (num char(5), channel varchar(20), isop int(1), isvoice int(1), code int(5));");
$sth->execute;

$sth = $dbh->prepare("CREATE TABLE server (name varchar(40), num char(2), hub char(2), numcode int(5), hubcode int(5));");
$sth->execute;
$sth = $dbh->prepare("CREATE TABLE uptime (uptime int(10))");
$sth->execute;

$sth=$dbh->prepare("DROP TABLE IF EXISTS ckey;");
$sth->execute;
$sth=$dbh->prepare("CREATE TABLE ckey (channel varchar(20), ckey varchar(20));");
$sth->execute;
my $uptime = time;
$sth = $dbh->prepare("INSERT INTO uptime VALUES ('$uptime');");
$sth->execute;
$remote = IO::Socket::INET->new("$host:$port") or die "Cannot connect!";


print $remote "PASS :$pass\n";
my $time = time;
print $remote "SERVER $servername 1 $time $time J10 $num".']]]'." :$descrip\n";
print $remote "$num N $csnick 1 $time $csident $bothost +dik bla $csnum :$csname\n";
print $remote "$num N $nsnick 1 $time $nsident $bothost +dik bla $nsnum :$nsname\n";
print $remote "$num N $osnick 1 $time $osident $bothost +dik bla $osnum :$osname\n";
print $remote "$num N $msnick 1 $time $msident $bothost +dik bla $msnum :$msname\n";

print $remote "$csnum J \#csworld\n";
print $remote "$nsnum J #csworld\n$osnum J #csworld\n$msnum J #csworld\n";

############################################
# START PARSING PROTOCOL 10 (u2.10.10.pl18)#
###########################################

while (<$remote>) {
    chop $_; chop $_;
    my @input = split(/ /,$_);
    if ($debug) {
	print "[READ] : $_\n";
    }

    if ($input[1] eq 'G') {
	print $remote "$num Z :Hello Pong u!\n";
    }

    if ($input[1] eq 'B') {
	  parse::burst($dbh,\@input,$csnum,$cdebug,$remote);
    }
    if ($input[1] eq 'EB' && $EA == 0) {
	    parse::endburst($dbh,$remote,$csnum,$cdebug,$num);
	    $EA = 1;
     
    }
    if ($input[1] eq 'N') {
	  nicks::new($dbh,$remote,$nsnum,$cdebug,\@input);
    }

    if ($input[1] eq 'M') {
      modes::new($dbh,\%cbans,\@input);
    }
    if ($input[1] eq 'J') {
      parse::join($dbh,$input[0],$input[2],$remote,$csnum);
    }
    if ($input[1] eq 'C') {
      parse::create($dbh,$input[0],$input[2]);
    }
    if ($input[1] eq 'L') {
      parse::part($dbh,$input[0],$input[2]);
    }
    if ($input[1] eq 'K') {
      parse::kick($dbh,\@input);
    }
    if ($input[1] eq 'Q') {
      parse::quit($dbh,$input[0],$input[2]);
    }
    if ($input[0] eq 'SERVER') {
      server::hub($dbh,$_);
    }
    if ($input[1] eq 'S') {
      server::new($dbh,$_);
    }
    if ($input[1] eq 'SQ') {
      server::squit($dbh,$_);
    }
    if ($input[1] eq 'MO') {
      motd::motd($remote,$input[0],$num);
    }





###############
#COMMAND BLOCK#
###############
    if ($input[1] eq 'P') {
	my $cs2 = "$csnick\@$servername";
	$cs2 = lc($cs2);
        my $ns2 = "$nsnick\@$servername";
        $ns2 = lc($ns2);
        $input[3] = lc($input[3]);
	if ($input[2] eq $nsnum || lc($input[2]) eq $ns2) {
	    if ($input[3] eq ':help') {
	      nshelp::nshelp($nsnum,$nsnick,$VER,$NETWORK,$remote,\@input,$servername);
	    }
	    elsif ($input[3] eq ':version') {
	      csversion::csversion($csnum,$VER,$remote,$input[0]);
	    }
	    elsif ($input[3] eq ':register') {
	      nsregister::nsregister($nsnum,$dbh,$remote,\@input);
	    }
	    elsif ($input[3] eq ':myinfo') {
	      nsmyinfo::nsmyinfo($nsnum,$dbh,$remote,\@input);
	    }
	    elsif ($input[3] eq ':newpass') {
	      nsnewpass::nsnewpass($nsnum,$dbh,$remote,$input[4],$input[5],$input[0]);
	    }
	    elsif ($input[3] eq ':identify') {
	      nsidentify::nsidentify($nsnum,$dbh,$remote,\@input,$ns2);
	    }
	    elsif ($input[3] eq ':info') {
	      nsinfo::nsinfo($dbh,$input[4],$input[0],$nsnum,$remote);
	    }
	    elsif ($input[3] eq ':whois') {
	      nswhois::nswhois($dbh,$remote,$nsnum,\@input);
	    }
	    elsif ($input[3] eq ':unregister') {
	      nsunregister::nsunregister($dbh,$remote,$nsnum,\@input,$csnum);
	    }
	    elsif ($input[3] eq ':recover') {
	      nsrecover::nsrecover($dbh,$remote,\@input,$nsnum);
	    }
	    else {
		$input[3] =~ s/://;
		print $remote "$nsnum O $input[0] :No Such Command - $input[3]\n";
	    }
	}

	if ($input[2] eq $csnum || lc($input[2]) eq $cs2) {
	    if ($input[3] eq ':help') {
	      cshelp::cshelp($csnum,$csnick,$VER,$NETWORK,$remote,\@input);
	    }
	    elsif ($input[3] eq ':version') {
	      csversion::csversion($csnum,$VER,$remote,$input[0]);
	    }
	    elsif ($input[3] eq ':uptime') {
	      csuptime::csuptime($uptime,$csnum,$remote,$input[0]);
	    }
	    elsif ($input[3] eq ':info') {
	      csinfo::csinfo($csnum,$remote,$dbh,\@input);
	    }
	    elsif ($input[3] eq ':register') {
	      csregister::csregister($dbh,$remote,\@input,$csnum);
	    }
	    elsif ($input[3] eq ':access') {
	      csaccess::csaccess($dbh,$remote,\@input,$csnum);
	    }
	    elsif ($input[3] eq ':opme') {
	      csopme::csopme($dbh,$remote,\@input,$csnum);
	    }
	    elsif ($input[3] eq ':op') {
	      csop::csop($dbh,$remote,\@input,$csnum);
	    }
	    elsif ($input[3] eq ':drop') {
	      csdrop::csdrop($dbh,$remote,\@input,$csnum);
	    }
	    elsif ($input[3] eq ':add') {
	      csadd::csadd($dbh,$remote,\@input,$csnum);
	    }
	    elsif ($input[3] eq ':remove') {
	      csremove::csremove($dbh,$remote,\@input,$csnum);
	    }
	    elsif ($input[3] eq ':edit') {
	      csedit::csedit($dbh,$remote,\@input,$csnum);
	    }
	    elsif ($input[3] eq ':list') {
	      cslist::cslist($dbh,$remote,\@input,$csnum);
            }
	    elsif ($input[3] eq ':aop') {
	      csaop::csaop($dbh,$remote,\@input,$csnum);
	    }
	    elsif ($input[3] eq ':voiceme') {
	      csvoiceme::csvoiceme($dbh,$remote,$csnum,\@input);
	    }
	    elsif ($input[3] eq ':invite') {
	      csinvite::csinvite($dbh,$remote,\@input,$csnum);
	    }
	    elsif ($input[3] eq ':voice') {
	      csvoice::csvoice($dbh,$remote,\@input,$csnum);
	    }
	    elsif ($input[3] eq ':cycle') {
	      cscycle::cscycle($dbh,$remote,\@input,$csnum);
	    }
	    elsif ($input[3] eq ':seturl') {
	      csseturl::csseturl($dbh,$remote,\@input,$csnum);
	    }
	    elsif ($input[3] eq ':deop') {
	      csdeop::csdeop($dbh,$remote,\@input,$csnum);
	    }
	    else {
		$input[3] =~ s/://;
		print $remote "$csnum O $input[0] :No such command - $input[3]\n";
	    }
	}




	if ($input[2] eq $osnum) {
	    $input[3] = lc($input[3]);
	    $input[3] =~ s/://;
	    $sth=$dbh->prepare("SELECT oper FROM ninfo WHERE num = '$input[0]' AND code = '".encode($input[0])."';");
	    $sth->execute;
	    my $oper = $sth->fetchrow_array;
	    if (!$oper) {
		print $remote "$osnum O $input[0] :Access denied.\n";
	    }
	    else {
		if ($input[3] eq 'register') {
		  osregister::osregister($dbh,$remote,\@input,$csnum);
		}
		elsif ($input[3] eq 'opers') {
		  osopers::osopers($dbh,$remote,\@input,$osnum);
	       }
		elsif ($input[3] eq 'regchan') {
#		  osregchan::osregchan($dbh,$remote,\@input,$osnum,$csnum);
		}

	    }
	}
	if ($input[2] eq $msnum) {
	    $input[3] = lc($input[3]);
	    $input[3] =~ s/://;
	    if ($input[3] eq 'help') {
	      mshelp::mshelp($dbh,$remote,\@input,$msnum,$NETWORK,$VER);
	    }
	    else {
		print $remote "$msnum O $input[0] :No such command.\n";
	    }
	}
    }

  


}


sub encode {
    my $code = $_[0];
    my @code = split(//,$code);
    my $return;
    foreach (@code) {
        if ($_ eq lc($_)) {
            $return .= '1';
        }
        else {
            $return .= '2';
        }
    }
    return $return;
}                
